package com.ihg.hiex.admin.service.account.impl;

import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.page.Page;
import com.demo2do.core.persistence.annotation.Dao;
import com.demo2do.core.utils.CollectionUtils;
import com.ihg.hiex.admin.dao.account.AccountDao;
import com.ihg.hiex.admin.dao.account.AssessorDao;
import com.ihg.hiex.admin.dao.session.EmailTemplateDao;
import com.ihg.hiex.admin.service.DataServiceImpl;
import com.ihg.hiex.admin.service.account.AssessorService;
import com.ihg.hiex.entity.data.ElearningSource;
import com.ihg.hiex.entity.data.notice.EmailTemplate;
import com.ihg.hiex.entity.session.SessionNotification;
import com.ihg.hiex.entity.user.Account;
import com.ihg.hiex.entity.user.Assessor;
import com.ihg.hiex.entity.user.AssessorCertificateRecord;
import com.ihg.hiex.entity.user.AssessorElearning;

/**
 * 
 * @author ZEAL
 *        
 */
@Service("assessorService")
public class AssessorServiceImpl extends DataServiceImpl<Assessor> implements AssessorService {
    
    @Dao
    private AccountDao accountDao;
    
    @Dao
    private AssessorDao assessorDao;
    
    @Dao
    private EmailTemplateDao emailTemplateDao;
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.account.AssessorService#listAssessor(java.lang.Long)
     */
    public List<Assessor> listAssessor(Long currentSessionId) {
        return assessorDao.list(currentSessionId);
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.account.AssessorService#countCertificateAssessor()
     */
    public int countCertificateAssessor() {
        return assessorDao.count();
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.account.AssessorService#listCertificateAssessor(com.demo2do.core.entity.page.Page)
     */
    public List<Assessor> listCertificateAssessor(Page page) {
        List<Assessor> result = assessorDao.list(page.getBeginIndex(), page.getMaxResultRecords());
        page.calculate();
        return result;
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.account.AssessorService#create(com.ihg.hiex.entity.user.Assessor)
     */
    public void create(Assessor assessor) {
        
        // 1. load account by email
        Account account = accountDao.loadByEmail(assessor.getEmail().toLowerCase());
        
        if (account == null) {      // 2.1 if account no exit
            
            // 2.1.1 save a new account
            account = new Account(assessor);
            genericDaoSupport.save(account.initialize());
            
            // 2.1.2 save a new assessor
            assessor.initialize(account);
            genericDaoSupport.save(assessor);
           
        } else {                    // 2.2. if account exit
            
            // 2.2.1 if account is assessor, create fail
            if (account.hasAuthority("ASSESSOR")) {
                throw BusinessException.newInstance("500", "创建失败，该用户已存在Assessor角色");
            }
            
            // 2.2.2 save assessor & update account authority
            genericDaoSupport.save(assessor.initialize(account));
            genericDaoSupport.update(account.addAuthority("ASSESSOR"));
            
        }
        
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.account.AssessorService#createCertificateAssessor(com.ihg.hiex.entity.user.Assessor, boolean)
     */
    public void createCertificateAssessor(Assessor assessor, boolean exist) {
        
        // create account and init assessor
        if(!exist) {
            this.create(assessor);
        }
        
        List<ElearningSource> elearningSources = assessorDao.listElearningSource(new String[]{"M1", "M2", "M3"});
        Map<String, ElearningSource> source = CollectionUtils.constructMapValue(elearningSources, "courseId");
        
        // create course M1's assessorElearning
        AssessorElearning assessorElearningOne = new AssessorElearning(source.get("M1"), assessor, "M1");
        genericDaoSupport.save(assessorElearningOne);
        
        // create course M2's assessorElearning
        AssessorElearning assessorElearningTwo = new AssessorElearning(source.get("M2"), assessor, "M2");
        genericDaoSupport.save(assessorElearningTwo);
        
        // create course M3's assessorElearning
        AssessorElearning assessorElearningThree = new AssessorElearning(source.get("M3"), assessor, "M3");
        genericDaoSupport.save(assessorElearningThree);
        
        // create assessorCertificateRecord
        AssessorCertificateRecord record = new AssessorCertificateRecord(assessor, assessorElearningOne, assessorElearningTwo, assessorElearningThree);
        genericDaoSupport.save(record);
        
        // update assessor
        genericDaoSupport.update(assessor.editCurrentCertificateRecordId(record.getId()));
        
        // create notification
        EmailTemplate emailTemplate = emailTemplateDao.load("certificateAssessorWelcome");
        SessionNotification sessionNotification = new SessionNotification(emailTemplate, assessor.getId());
        genericDaoSupport.save(sessionNotification);
    }
    
    /* (non-Javadoc)
     * @see com.ihg.hiex.admin.service.account.AssessorService#edit(com.ihg.hiex.entity.user.Assessor)
     */
    public void edit(Assessor assessor) {
        
        // 1. update account
        Account account = assessor.getAccount();
        account.edit(assessor.getTelephone());
        genericDaoSupport.update(account);
        
        // 2. update assessor
        genericDaoSupport.update(assessor.edit());
        
    }
    
    /* (non-Javadoc)
     * @see com.ihg.hiex.admin.service.account.AssessorService#disable(com.ihg.hiex.entity.user.Assessor)
     */
    public void disable(Assessor assessor) {
        
        // 1. get account by assessor
        Account account = assessor.getAccount();
        
        if (account.getAuthority().contains("ADMIN")) {       // 2.1 if account is administrator, then remove authority
            genericDaoSupport.update(account.removeAuthority("ASSESSOR"));
        } else {                                                // 2.2 if account is not administrator, then disable account
            genericDaoSupport.update(account.disable());
        }
        
        // 3. disable assessor
        genericDaoSupport.update(assessor.disable());
        
    }
    
}